/**
 * Copyright &copy; 2013-2015 山东易科德软件有限公司 All rights reserved.
 */
package cn.net.ecode.common.persistence;

import javax.validation.constraints.NotNull;

import org.hibernate.validator.constraints.Length;

import com.fasterxml.jackson.annotation.JsonBackReference;

import cn.net.ecode.common.config.Global;
import cn.net.ecode.common.utils.Reflections;
import cn.net.ecode.common.utils.StringUtils;

/**
 * 数据Entity类
 * @author ThinkGem
 * @version 2014-8-19
 */
public abstract class TreeEntity<T> extends DataEntity<T> {

	private static final long serialVersionUID = 1L;

	protected T parent; 			// 父级编号
	protected String parentCodes; 	// 所有父级编号
	protected Integer sorts; 		// 排序

	protected String hasnext; 		// 是否有下级节点
	protected Integer sortGrade; 	// 树层次级别
	
	protected String pid;//pid
	
	protected Boolean isQueryChildren; // 是查询子级数据

	public TreeEntity() {
		super();
		this.sorts = 30;
	}

	public TreeEntity(String id) {
		super(id);
	}

	/**
	 * 父对象，只能通过子类实现，父类实现mybatis无法读取
	 * @return
	 */
	@JsonBackReference
	@NotNull
	public abstract T getParent();

	/**
	 * 父对象，只能通过子类实现，父类实现mybatis无法读取
	 * @return
	 */
	public abstract void setParent(T parent);

	/**
	 * 获取上级节点编号
	 * @return
	 */
	public String getParentCode() {
		String id = null;
		if (parent != null){
			id = (String)Reflections.invokeGetter(parent, "id");
		}
		return id;
	}

	@SuppressWarnings("unchecked")
	public void setParentCode(String parentCode) {
		if (parent == null){
			try {
				parent = (T)this.getClass().newInstance();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		Reflections.invokeSetter(parent, "id", parentCode);
	}
	
	/**
	 * 获取所有父级编号
	 * @return
	 */
	@Length(min = 1, max = 2000)
	public String getParentCodes() {
		return parentCodes;
	}

	public void setParentCodes(String parentCodes) {
		this.parentCodes = parentCodes;
	}

	public Integer getSorts() {
		return sorts;
	}

	public void setSorts(Integer sorts) {
		this.sorts = sorts;
	}

	/**
	 * 获取子节点个数，需要mapper里查询取得
	 * oracle select: (case when (select count(1) from sys_menu where status = '0' and parent_code = a.menu_code) > 0 then '1' else '0' end) as "hasnext"
	 * oracle update: update sys_menu t set t.hasnext = '0'; update sys_menu t set t.hasnext = '1' where exists (select 1 from sys_menu where parent_code = t.menu_code);
	 * @return
	 */
	public String getHasnext() {
		return hasnext;
	}

	public void setHasnext(String hasnext) {
		this.hasnext = hasnext;
	}

	/**
	 * 获取树层次级别（从0开始）
	 * oracle select: (length(regexp_replace(a.parent_codes,'[^,]',''))) AS "sortGrade",
	 * oracle update: update sys_menu t set t.sort_grade = (length(regexp_replace(t.parent_codes,'[^,]','')));
	 * @return
	 */
	public Integer getSortGrade() {
		if (hasnext != null && sortGrade == null){
			sortGrade = parentCodes != null ? parentCodes.replaceAll("[^,]", "").length()-1 : null;
		}
		return sortGrade;
	}

	public void setSortGrade(Integer sortGrade) {
		this.sortGrade = sortGrade;
	}
	
	/**
	 * 是否叶子节点（hasnext不是1 或者 状态是不是正常的）
	 * @return
	 */
	public Boolean getIsLeaf(){
		if (hasnext != null){
			return !Global.YES.equals(hasnext) || !STATUS_NORMAL.equals(status);
		}
		return null;
	}

	/**
	 * 获取父节点 ，取不到返回（ROOT_CODE = "0"）
	 */
	public String getPid() {
		if (pid == null || StringUtils.isBlank(pid)) {
			String id = getParentCode();
			pid = StringUtils.isNotBlank(id) ? id : ROOT_CODE;
		}
		return pid;
	}
	
	public void setPid(String pid) {
		this.pid = pid;
	}

	/**
	 * 是否是根节点
	 * @return
	 */
	public boolean getIsRoot() {
		return ROOT_CODE.equals(getPid());
	}

	/**
	 * 是否查询包含子级
	 * @return
	 */
	public Boolean getIsQueryChildren() {
		return isQueryChildren;
	}

	public void setIsQueryChildren(Boolean isQueryChildren) {
		this.isQueryChildren = isQueryChildren;
	}

	/**
	 * Tree根节点ID
	 */
	public static final String ROOT_CODE = "0";

//	// 有下级节点
//	public static final String HASNEXT_YES = "1";  请用 Global.YES
//	// 没有下级节点
//	public static final String HASNEXT_NO = "0";   请用 Global.NO


}
